<template>
  <el-card>
    <el-form v-loading="loading">
      <el-form-item class="table-layout">
        <template v-for="item of items">
          <el-row class="th" :key="item.id + '_th'">
            <el-checkbox
              v-model="item.selected"
              @change="onCheckAllChange(item)"
              :indeterminate="item.indeterminate && !item.selected"
              >{{ item.name }}</el-checkbox
            >
          </el-row>
          <el-row class="tr" :key="item.id">
            <el-col
              v-for="resource of item.resourceList"
              :key="resource.id"
              :span="8"
              class="td"
            >
              <el-checkbox
                v-model="resource.selected"
                @change="onCheckItemChange(item)"
                >{{ resource.name }}</el-checkbox
              >
            </el-col>
          </el-row>
        </template>
      </el-form-item>
      <el-form-item style="text-align: center">
        <el-button @click="submit" type="primary">保存</el-button>
        <el-button @click="clear">清空</el-button>
      </el-form-item>
    </el-form>
  </el-card>
</template>
<script lang="ts">
import { getAllResources, allocateResources } from '@/services/role'
import { HasId, ID } from '@/types'
import { wrapAsyncWithLoading } from '@/utils/helper'
import Vue from 'vue'

function isIndeterminate (items: any[] | null, key: string) {
  if (!items) return false
  return items.some(item => item[key])
}
function visitTreeNode (node: any | any[], subNodesKey: string, visitNode: Function) {
  if (Array.isArray(node)) {
    node.forEach(item => visitTreeNode(item, subNodesKey, visitNode))
    return
  }
  visitNode(node)
  if (node[subNodesKey]) {
    node[subNodesKey].forEach((element: any) => visitTreeNode(element, subNodesKey, visitNode))
  }
}
export default Vue.extend({
  name: 'role-alloc-resource',
  props: {
    id: [String, Number]
  },
  data () {
    return {
      loading: false,
      items: []
    }
  },
  created () {
    wrapAsyncWithLoading(this, 'loading', 'loadItems')
    wrapAsyncWithLoading(this, 'loading', 'submit')
    this.loadItems()
  },
  methods: {
    async loadItems () {
      const { data } = await getAllResources(this.id)
      const items = data.data
      items.sort(({ id: a }: HasId, { id: b }: HasId) => a > b ? 1 : -1)
      items.forEach((item: any) => {
        item.indeterminate = isIndeterminate(item.resourceList, 'selected')
      })
      this.items = data.data
    },
    onCheckAllChange (item: any) {
      const checked = item.selected
      for (const resource of item.resourceList) {
        resource.selected = checked
      }
    },
    onCheckItemChange (item: any) {
      item.selected = item.resourceList.every((resource: any) => resource.selected)
      item.indeterminate = isIndeterminate(item.resourceList, 'selected')
    },
    clear () {
      visitTreeNode(this.items, 'resourceList', (item: any) => {
        item.selected = false
        item.indeterminate = false
      })
    },
    async submit () {
      const resourceList = [] as ID[]
      visitTreeNode(this.items, 'resourceList', (item: any) => {
        if (item.selected) {
          resourceList.push(item.id)
        }
      })
      const { data } = await allocateResources(this.id, resourceList)
      if (data.code === '000000') {
        this.$message.success('分配资源成功')
      }
    }
  }
})
</script>
<style lang="scss" scoped>
.table-layout {
  border: 1px solid #dcdfe6;
  border-bottom: 0 none;
}
.th {
  background-color: #f2f6fc;
  border-bottom: 1px solid #dcdfe6;
  padding: 20px;
}
.tr {
  border-bottom: 1px solid #dcdfe6;
  padding: 20px;
}
.td {
  padding: 4px 0;
}
</style>
